//
//  GLView.mm
//  SypX
//
//  Created by Luv Khemani on 5/7/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#include "Engine.h"
#include "CanvasiPhoneGL.h"
#import "GLView.h"
#include "Event.h"


@implementation GLView
@synthesize context;
@synthesize displayLink;

+ (Class) layerClass
{
	return [CAEAGLLayer class];//return the class type of GLView's layer (we are downcasting to CAEAGLLayer)
}


- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint location  = [touch locationInView: self];
	SypX::Event e;
	e.type = SypX::TOUCHDOWN;
	e.location.x = location.x;
	e.location.y = self.bounds.size.height - location.y;
	eventQue.push_back(e);
}

- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint location  = [touch locationInView: self];
	SypX::Event e;
	e.type = SypX::TOUCHUP;
	e.location.x = location.x;
	e.location.y = self.bounds.size.height - location.y;
	eventQue.push_back(e);
}

- (std::deque<SypX::Event>*) getEventList
{
	return &eventQue;
}

- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];
    CGPoint previous  = [touch previousLocationInView: self];
    CGPoint current = [touch locationInView: self];
	
	SypX::Event e;
	e.type = SypX::TOUCHMOVE;
	SypX::Event::DragData d;
	d.curr.x = current.x;
	d.curr.y = self.bounds.size.height - current.y;
	d.prev.x = previous.x;
	d.prev.y = self.bounds.size.height - previous.y;
	e.moved = d;
	eventQue.push_back(e);
}

- (void) didRotate: (NSNotification*) notification
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    
	SypX::Event e;
	
	switch (orientation) {
		case UIDeviceOrientationUnknown:
			e.type = SypX::DeviceOrientationUnknown;
			break;
		case UIDeviceOrientationPortrait:
			e.type = SypX::DeviceOrientationPortrait;
			break;
		case UIDeviceOrientationPortraitUpsideDown:
			e.type = SypX::DeviceOrientationPortraitUpsideDown;
			break;
		case UIDeviceOrientationLandscapeLeft:
			e.type = SypX::DeviceOrientationLandscapeLeft;
			break;
		case UIDeviceOrientationLandscapeRight:
			e.type = SypX::DeviceOrientationLandscapeRight;
			break;
		case UIDeviceOrientationFaceUp:
			e.type = SypX::DeviceOrientationFaceUp;
			break;
		case UIDeviceOrientationFaceDown:
			e.type = SypX::DeviceOrientationFaceDown;
			break;

	}
	
	eventQue.push_back(e);
	//m_renderingEngine->OnRotate((DeviceOrientation) orientation);
    //[self drawView: nil];
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
		CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;//downcast UIView's layer to CAEAGLLayer
		eaglLayer.opaque = YES;
		
		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];//allocate a GLES1 context
		if(!context || ![EAGLContext setCurrentContext:context])
		{//if we cannot create GLcontext or cannot set it to current
			[self release];//release GLView
			return nil;
		}     

		
		
		//Call our init function since we have our UIView up now, this should lead to init of all subsystems
		//including our Renderer to be initialised
		SypX::Engine::getSingleton()->init();	
	
		//Note: Renderer must be init before following line to take effect. Which is why we call user init here
		
		[context
		 renderbufferStorage:GL_RENDERBUFFER_OES
		 fromDrawable: eaglLayer];									//Connect/Bind our UIView/GLView's layer to the context
				
	
		
										//Create a displayLink 
        displayLink = [CADisplayLink displayLinkWithTarget:self		//Link displayLink with our paint/draw callback function
												  selector:@selector(drawView:)];
        
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop]		//Add our newly created displayLink with IPhone's main loop
						  forMode:NSDefaultRunLoopMode];
		
		[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];		//Enable Device Orientation collection
		[[NSNotificationCenter defaultCenter]							//Send Orientation changes to didRotate
		 addObserver:self
		 selector:@selector(didRotate:)
		 name:UIDeviceOrientationDidChangeNotification
		 object:nil];
		
    }
    return self;
}

-(void)drawView:(CADisplayLink*) dispLink
{
	SypX::Engine::getSingleton()->runFunction();
	
}


-(void)swapBuffers
{
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void)dealloc {

	[displayLink release];
	if([EAGLContext currentContext] == context)	//if our GL context is the current context
		[EAGLContext setCurrentContext:nil];	//unbind it 
		
	[context release];							//release our glcontext
	 
	[super dealloc];
}


@end
